﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Serialization;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;

namespace CrashSimul8or
{
    //Gagnagrind utanum resources
    public class Resource
    {
        public int type;
        public string name;
        public string loc;
    }

    //Auðveldar að lesa inn úr XML
    public class Resources
    {
        public List<Resource> ResourceDefinitions;
    }

    class ResourceManager 
    {
        static Resources resources;
        static private int totalResourceCount;
        static private int totalFinishedLoading;
        static private ContentManager Content;

        static Dictionary<string, Texture2D> textures;
        static Dictionary<string, SpriteFont> fonts;
        static Dictionary<string, SoundEffect> sounds;
        static Dictionary<string, Song> songs;
        static Dictionary<string, Effect> effects;

        /// <summary>
        /// Bendir ResourceManager á ContentManager til að nota.
        /// </summary>
        /// <param name="target">Viðeigandi ContentManager</param>
        public static void initResourceManager(ContentManager target)
        {
            Content = target;
        }

        /// <summary>
        /// Aðferð les inn upplýsingar um resources og hvar þær eru geymdar en
        /// hleður þeim ekki inní minni að undanskilinni loading mynd.
        /// </summary>
        /// <param name="target">Strengur sem bendir á XML skránna</param>
        public static void loadResourceData(string target) {
            //Hlaða inn upplýsingum úr XML
            var fileStream = new FileStream("Content/"+target, FileMode.Open);
            var xmlSerializer = new XmlSerializer(typeof(Resources));
            resources = (Resources)xmlSerializer.Deserialize(fileStream);

            textures = new Dictionary<string,Texture2D>();
            fonts = new Dictionary<string, SpriteFont>();
            sounds = new Dictionary<string, SoundEffect>();
            songs = new Dictionary<string, Song>();
            effects = new Dictionary<string, Effect>();

            //Hlaða inn loading myndinni
            /*
            foreach(Resource i in resources.ResourceDefinitions)
            {
                if (i.name == "loading")
                {
                    Resource temp = i;
                    resources.ResourceDefinitions.Remove(temp);
                    textures.Add(temp.name, Content.Load<Texture2D>(temp.loc));
                    break;
                }
            }
            */
            totalResourceCount = resources.ResourceDefinitions.Count;
            totalFinishedLoading = 0;
        }

        /// <summary>
        /// Skilar float tölu sem segir til hvað er búið að hlaða inn í minni
        /// mörgum resource-um.
        /// </summary>
        /// <returns>Hlutfall af hlöðnum resourceum</returns>
        public static float getLoadingProgress()
        {
            return (float)totalFinishedLoading / (float)totalResourceCount;
        }

        /// <summary>
        /// Aðferð sem hleður inní minni þeirri resource sem er fremst í
        /// listanum resources.ResourceDefinitions
        /// </summary>
        public static void loadNextResource()
        {
            if (resources.ResourceDefinitions.Count == 0)
            {
                //System.Console.WriteLine("No more resources to load!");
                return;
            }
            Resource temp = null;
            //Vel fyrsta í listanum
            foreach(Resource i in resources.ResourceDefinitions)
            {
                temp = i;
                break;
            }

            //Eyði henni úr lista
            resources.ResourceDefinitions.Remove(temp);

            //Hleð henni inní Hashmap
            switch (temp.type)
            {
                case 1:
                    textures.Add(temp.name, Content.Load<Texture2D>(temp.loc));
                    break;
                case 2:
                    fonts.Add(temp.name, Content.Load<SpriteFont>(temp.loc));
                    break;
                case 3:
                    sounds.Add(temp.name, Content.Load<SoundEffect>(temp.loc));
                    break;
                case 4:
                    songs.Add(temp.name, Content.Load<Song>(temp.loc));
                    break;
                case 5:
                    effects.Add(temp.name, Content.Load<Effect>(temp.loc));
                    break;
                default:
                    throw new System.ArgumentException("Óþekkt resource type í xml: "+Convert.ToString(temp.type), "original");
            }
            totalFinishedLoading++;
        }

        /// <summary>
        /// Nær í texture eftir nafni sem gefið var upp í XML skránni.
        /// </summary>
        /// <param name="target">Nafn á texture sem þú vilt ná í</param>
        /// <returns>Viðeigandi texture</returns>
        public static Texture2D getTexture(string target)
        {
            try
            {
                return textures[target];
            }
            catch (KeyNotFoundException x)
            {
                throw new System.ArgumentException("Vantar eftirfarandi mynd í contentfolder eða XML bendir á vitlausann stað: "+target+".", x);
            }
        }

        /// <summary>
        /// Nær í font eftir nafni sem gefið var upp í XML skránni.
        /// </summary>
        /// <param name="target">Nafn á fontinum sem þú vilt ná í</param>
        /// <returns>Viðeigandi font</returns>
        public static SpriteFont getFont(string target)
        {
            try
            {
                return fonts[target];
            }
            catch (KeyNotFoundException x)
            {
                throw new System.ArgumentException("Vantar eftirfarandi font í contentfolder eða XML bendir á vitlausann stað: " + target + ".", x);
            }
        }

        /// <summary>
        /// Nær í sound eftir nafni sem gefið var upp í XML skránni.
        /// </summary>
        /// <param name="target">Nafn á soundinu sem þú vilt ná í</param>
        /// <returns>Viðeigandi sound</returns>
        public static SoundEffect getSound(string target)
        {
            try
            {
                return sounds[target];
            }
            catch (KeyNotFoundException x)
            {
                throw new System.ArgumentException("Vantar eftirfarandi sound í contentfolder eða XML bendir á vitlausann stað: " + target + ".", x);
            }
        }

        /// <summary>
        /// Nær í sound eftir nafni sem gefið var upp í XML skránni.
        /// </summary>
        /// <param name="target">Nafn á soundinu sem þú vilt ná í</param>
        /// <returns>Viðeigandi sound</returns>
        public static Song getSong(string target)
        {
            try
            {
                return songs[target];
            }
            catch (KeyNotFoundException x)
            {
                throw new System.ArgumentException("Vantar eftirfarandi song í contentfolder eða XML bendir á vitlausann stað: " + target + ".", x);
            }
        }

        /// <summary>
        /// Nær í effect eftir nafni sem gefið var upp í XML skránni.
        /// </summary>
        /// <param name="target">Nafn á effectinu sem þú vilt ná í</param>
        /// <returns>Viðeigandi effect</returns>
        public static Effect getEffect(string target)
        {
            try
            {
                return effects[target];
            }
            catch (KeyNotFoundException x)
            {
                throw new System.ArgumentException("Vantar eftirfarandi effect í contentfolder eða XML bendir á vitlausann stað: " + target + ".", x);
            }
        }
    }
}
